"""
@Time : 2024/1/7 10:21
@Auth : Mr.Zhao
#Function : app自动化测试操作层
"""
import json
import logging
import time
import os
import threading
from common.Logging import logger
from appium import webdriver
from appium.options.common.base import AppiumOptions

class App:
    """app自动化测试常用操作层封装"""
    def __init__(self, port:str = '4723'):
        self.port = port
        self.driver: webdriver.Remote = None
        self.flag = False #表明appium进程是否启动
        pass

    def stop_appium(self, port = ''):
        #启动和关闭通用一个port
        if not port:
            port = self.port
        with os.popen(f"netstat -aon | findstr 4723") as f:
            res = f.read().split('\n')  # 首先通过‘\n’分割后，只取第一个元素（避免查找到多个套接字，一般只有第一个是预期情况）
            if res:
                res = res[0]  # 截取第一个元素
            else:
                logger.warning("没有找到指定的appium进程....")
                return
            res = res.split(' ')  # 通过' '分割为列表以获取最后一个元素
            pid = res[-1]  # 获取pid
            os.system(f"taskkill /F /pid {pid}")
            self.flag = False
            logger.info(f"已经结束了pid为{pid}的进程...")

    def run_appium(self, port:str = '4723'):
        """启动appium服务,若已经启动，则先关闭"""
        if self.flag == True:
            self.stop_appium()
        self.port = port
        def __run_appium():
            os.system(
                rf"node D:\Pycharm\APP\Appium-Server-GUI-windows-1.22.3-4\resources\app\node_modules\appium\build\lib\main.js -p {port} --chromedriver-executable ddd")
        th1 = threading.Thread(target = __run_appium)
        th1.start()
        logging.info("appium正在启动中......")
        self.flag = True
        time.sleep(2)

    def run_app(self, conf:str = ''):
        """
        启动指定app,需要传入json字符串
        :param conf: json字符串配置
        :return:
        """
        conf = json.loads(conf) #将json格式字符串加载为json配置
        os.system(rf"adb connect {conf.get('appium:deviceName')}")
        with os.popen("adb devices") as f:
            logger.info(f.read()) #来观察adb是否启动成功并成功连接设备
        conf['udid'] = conf.get('deviceName')
        options = AppiumOptions()
        options.load_capabilities(conf)
        logger.info("app正在启动......")
        #driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", conf)  # 创建远程WebDriver对象
        self.driver = webdriver.Remote(f"http://127.0.0.1:{self.port}/wd/hub", options=options)
        self.driver.implicitly_wait(10)
        time.sleep(10)
        logger.info("app已经启动成功......")

    def __find_ele(self, lo:str = ''):
        """
        返回元素位置，支持xpath，ID，accessibility id(windows相当于描述)
        :param lo:
        :return:
        """
        if lo.startswith('/') or lo.startswith('('):
            ele = self.driver.find_element('xpath', lo)
        elif lo.__contains__(':id/'):
            ele = self.driver.find_element('id', lo)
        else:
            ele = self.driver.find_element('accessibility id', lo)
        return ele

    def click(self, lo:str = ''):
        """
        点击元素
        :param lo:
        :return:
        """
        ele = self.__find_ele(lo)
        ele.click()

    def sleep(self, t:str = '1'):
        """
        强制等待，参数错误或不传参默认为1
        :param t:
        :return:
        """
        try:
            t = int(t)
        except:
            t = 1
        time.sleep(t)

    def quit(self):
        time.sleep(1)
        if self.driver:
            self.driver.quit()
        self.driver = None


    def keyevent(self, keycode='66'):
        """
        按键
        :param keycode: 默认66，回车
        """
        try:
            keycode = int(keycode)
        except:
            keycode = 66

        self.driver.keyevent(keycode)


    def input(self, lo: str = '', text: str = '', is_clear: str = ''):
        """
        输入文本
        :param lo: 定位
        :param text: 需要输入的字符串
        :param is_clear: 输入任意字符都代表先清空再输入
        :return:
        """
        ele = self.__find_ele(lo)
        if is_clear:
            ele.clear()
            ele.send_keys(text)
        else:
            ele.send_keys(text)

if __name__ == "__main__":
    conf = """
    {
      "platformName": "Android",
      "appium:deviceName": "127.0.0.1:7555",
      "appium:appPackage": "com.tencent.mobileqq",
      "appium:appActivity": ".activity.SplashActivity",
      "appium:noReset": "true"
    }"""
    app = App()
    app.run_appium()
    app.run_app(conf)
    time.sleep(2)
    app.stop_appium()
